#include <rtdef.h>
#include <rtthread.h>
#include "Flash.h"
#include "MQ.h"

#define DRV_DEBUG 1
#define LOG_TAG     "flash.spi"
#include <drv_log.h>
rt_mq_t flash_mq;

rt_device_t Flashdev;

// 提交 Flash 操作请求
static rt_err_t flash_submit_request(flash_req_t *req)
{
    if( flash_mq ==RT_NULL)
    {
        return RT_ERROR;
    }
    return rt_mq_send(flash_mq, &req, sizeof(req));
}

// 同步写入接口
rt_err_t flash_write_sync(rt_uint32_t addr, const void *data, rt_uint32_t size)
{
    rt_err_t result;
    struct rt_semaphore sem;
    flash_req_t req = {
        .op_type = FLASH_OP_WRITE,
        .addr = addr,
        .size = size,
        .data = (void*)data,
        .completion_sem = &sem,
        .result = RT_EOK
    };
    
    // 初始化信号量
    rt_sem_init(&sem, "flash_sync", 0, RT_IPC_FLAG_FIFO);
    
    // 提交请求
    result = flash_submit_request(&req);
    if (result != RT_EOK) {
        rt_sem_detach(&sem);
        return result;
    }
    
    // 等待操作完成
    rt_sem_take(&sem, RT_WAITING_FOREVER);
    rt_sem_detach(&sem);
    
    return req.result;
}

// 同步读接口
rt_err_t flash_Read_sync(rt_uint32_t addr, const void *data, rt_uint32_t size)
{
    rt_err_t result;
    struct rt_semaphore sem;
    flash_req_t req = {
        .op_type = FLASH_OP_READ,
        .addr = addr,
        .size = size,
        .data = (void*)data,
        .completion_sem = &sem,
        .result = RT_EOK
    };
    
    // 初始化信号量
    rt_sem_init(&sem, "flash_sync", 0, RT_IPC_FLAG_FIFO);
    
    // 提交请求
    result = flash_submit_request(&req);
    if (result != RT_EOK) {
        rt_sem_detach(&sem);
        return result;
    }
    
    // 等待操作完成
    rt_sem_take(&sem, RT_WAITING_FOREVER);
    rt_sem_detach(&sem);
    
    return req.result;
}

void Flash_thread_entry(void *parameter)
{
    rt_err_t result;
    flash_req_t *req;
    // 初始化消息队列
//    result = rt_mq_init(flash_mq, "flash_mq",&flash_mq_pool[0],sizeof(flash_req_t*),sizeof(flash_mq_pool),RT_IPC_FLAG_FIFO);
    flash_mq = rt_mq_create("flash_mq", sizeof(flash_req_t*), 10, RT_IPC_FLAG_FIFO);
    if( flash_mq == RT_NULL)
    {
        LOG_I("create flash mq error\r\n");
    }
    Flashdev = rt_device_find(FLASH_SPI_DEVICE_NAME);
    if(Flashdev)
    {
        rt_thread_mdelay(1000);
        rt_device_open(Flashdev, RT_DEVICE_OFLAG_RDWR);
        spi_dev = (struct rt_spi_device *)Flashdev;
    }
    else
    {
        LOG_I("Flashdev dev open error\r\n");
    }
        
    while(1)
    {
        if ( rt_mq_recv(flash_mq, &req, sizeof(req), RT_WAITING_FOREVER )) 
        {
            switch (req->op_type) 
            {
                case FLASH_OP_ERASE://擦除
                    LOG_I("Flash FLASH_OP_ERASE");
                    break;
                case FLASH_OP_WRITE://写
                    LOG_I("Flash FLASH_OP_WRITE");
                    WriteExtFlash(CS_SPI_FLASH, req->addr, req->size, req->data );
                    break;
                case FLASH_OP_READ://读
                    LOG_I("Flash FLASH_OP_READ");
                    ReadExtFlash(CS_SPI_FLASH, req->addr, req->size, req->data );
                    break;
                case FLASH_OP_VERIFY:
                    break;
                default:
                    break;
            }
            if (req->completion_sem != RT_NULL) 
            {
                rt_sem_release(req->completion_sem);
            }
        }
    }
}
